package com.crack.nga2.custom;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.TranslateAnimation;
import android.widget.AbsListView;
import android.widget.ListAdapter;
import android.widget.ListView;

/**
 * 下拉刷新listView
 * Created by Administrator on 2015/12/18.
 */
public class PullListView extends ListView implements AbsListView.OnScrollListener {

    public PullListView(Context context) {
        super(context);
    }

    public PullListView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public void setAdapter(ListAdapter adapter) {
        initView();
        super.setAdapter(adapter);
        if (noPullUp) {
            removeFooterView(footerLayout.getView());
        }
    }

    private ILoadingLayout headerLayout;
    private ILoadingLayout footerLayout;

    public void setHeaderLayout(ILoadingLayout headerLayout) {
        this.headerLayout = headerLayout;
    }

    private void initView() {
        if (headerLayout == null) {
            headerLayout = new HeadLayoutImpl(getContext());
            addHeaderView(headerLayout.getView(), null, false);
        }
        footerLayout = new FootLayoutImpl(getContext());
        addFooterView(footerLayout.getView(), null, false);
        footerLayout.getView().setVisibility(View.GONE);
        setOnScrollListener(this);
        state = DONE;
        isInEditMode();
    }

    private static final int LOADING = 1;
    private static final int DONE = 2;
    private static final int PULLING = 3;
    private static final int MODE_UP = 4;
    private static final int MODE_DOWN = 5;
    /**
     * 顶部拉升高度
     */
    public static int MAX_HEIGHT = 120;
    public static int RATIO = 4;
    /**
     * 底部临界高度
     */
    public static int BOTTOM_HEIGHT = 30;
    private int state;
    private boolean refreshable;
    private boolean isRecord;
    private int startY;
    private OnRefreshListener listener;
    private int mode = MODE_DOWN;

    /**
     * 进入可上拉刷新状态
     */
    private boolean pullUp = false;

    /**
     * 禁用上拉
     */
    private boolean noPullUp = false;


    /**
     * 禁用上拉加载
     *
     * @param noPullUp true：禁用
     */
    public void setNoPullUp(boolean noPullUp) {
        this.noPullUp = noPullUp;
    }

    /**
     * 下拉时的拉伸距离
     */
    private int pullY;

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        if (state == LOADING) {
            return super.onTouchEvent(ev);
        }
        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                //refreshable为true表示listView滚动到了最顶部
                if (refreshable) {
                    //isRecord标记初始位置（startY）是否被记录 如果没有记录则给startY赋值并将isRecord置为true
                    if (!isRecord) {
                        startY = (int) ev.getY();
                        isRecord = true;
                    }
                }
                if (pullUp && !refreshable) {
                    if (!isRecord) {
                        startY = (int) ev.getY();
                        isRecord = true;
                    }
                }
                break;
            case MotionEvent.ACTION_MOVE:
                if (refreshable) {
                    if (!isRecord) {
                        startY = (int) ev.getY();
                        isRecord = true;
                    }
                    //DONE表示空闲状态(刷新已完成)
                    if (state == DONE) {
                        state = PULLING;
                    }
                    //计算出偏移量
                    int offset = (int) ev.getY() - startY;
                    if (state == PULLING) {
                        if (offset <= 0) {
                            //推回去 重新回到空闲状态
                            state = DONE;
                        } else if (offset > 0 && offset < MAX_HEIGHT) {
                            //继续下拉则调用顶部View的拉伸方法 并且保持位置定位在顶部 如果是关联外部刷新布局则无需定位
                            setSelection(0);
                            headerLayout.pullTo(pullY = offset * RATIO);
                        } else {
                            //进入刷新状态
                            state = LOADING;
                            backToAnimation();
                            headerLayout.stopPull();
                            headerLayout.startRefresh();
                            if (listener != null) {
                                listener.pullDownToRefresh();
                            }
                        }
                    }
                }
                if (pullUp) {
                    if (!isRecord) {
                        startY = (int) ev.getY();
                        isRecord = true;
                    }
                    //DONE表示空闲状态(刷新已完成)
                    if (state == DONE) {
                        state = PULLING;
                    }
                    //计算出偏移量
                    int offset = (int) ev.getY() - startY;
                    if (state == PULLING) {
                        if (offset >= 0) {
                            //推回去 重新回到空闲状态
                            state = DONE;
                        } else if (offset < 0 && offset > -BOTTOM_HEIGHT) {
                            footerLayout.pullTo(offset * RATIO);
                            state = PULLING;
                        } else {
                            footerLayout.stopPull();
                            footerLayout.startRefresh();
                            state = LOADING;
                            if (listener != null) {
                                listener.pullUpToRefresh();
                            }
                        }
                    }
                }
                break;
            case MotionEvent.ACTION_UP:
                if (state != LOADING) {
                    //回到空闲状态 记录清空
                    state = DONE;
                    isRecord = false;
                    if (mode == MODE_DOWN) {
                        headerLayout.stopPull();
                        backToAnimation();
                    }
                    if (mode == MODE_UP) {
                        footerLayout.stopPull();
                    }
                }
                break;
        }
        return super.onTouchEvent(ev);
    }

    /**
     * 松开后返回原位动画
     */
    private void backToAnimation() {
        /*
       Animation a = new TranslateAnimation(0,0,pullY,0);
        a.setDuration(100);
        this.startAnimation(a);
        pullY = 0;
        */
    }


    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {

    }

    @Override
    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
        if (firstVisibleItem == 0) {
            mode = MODE_DOWN;
            refreshable = true;
        } else {
            refreshable = false;
        }

        if (!noPullUp) {
            if (totalItemCount > 0 && firstVisibleItem + visibleItemCount == totalItemCount && !refreshable) {
                pullUp = true;
                footerLayout.getView().setVisibility(VISIBLE);
                mode = MODE_UP;
            } else {
                pullUp = false;
                footerLayout.getView().setVisibility(INVISIBLE);
            }
        }
    }

    /**
     * 结束刷新 通常用于数据载入完成后调用
     * 回到空闲状态 并清空记录
     */
    public void onCompleteRefresh() {
        if (state == LOADING) {
            if (mode == MODE_DOWN) {
                headerLayout.stopPull();
                headerLayout.stopRefresh();
            }
            if (mode == MODE_UP) {
                footerLayout.stopPull();
                footerLayout.stopRefresh();
            }
        }
        state = DONE;
        isRecord = false;
    }

    /**
     * 开启刷新动画 通常用于初始化数据时调用
     */
    public void onStartHeadRefresh() {
        headerLayout.startRefresh();
        state = LOADING;
        Log.i("tag", "listView开始刷新动画" + state);
    }


    public void setOnRefreshListener(OnRefreshListener listener) {
        this.listener = listener;
    }

    public interface OnRefreshListener {
        void pullDownToRefresh();

        void pullUpToRefresh();
    }

}
